Index: main/plugin-cms/sitemap.xmap
===================================================================
--- main/plugin-cms/sitemap.xmap	(revision 26960)
+++ main/plugin-cms/sitemap.xmap	(working copy)
@@ -39,6 +39,7 @@
             <map:generator name="common-metadataset" src="org.ametys.cms.contenttype.CommonMetadataSetNamesGenerator"/>
             <map:generator name="common-metadataset-from-contents" src="org.ametys.cms.contenttype.CommonMetadataSetNamesFromContentsGenerator"/>
             <map:generator name="common-metadata" src="org.ametys.cms.contenttype.CommonMetadataGenerator"/>
+            <map:generator name="common-typed-metadata" src="org.ametys.cms.contenttype.CommonTypedMetadataGenerator"/>
             <map:generator name="common-sortable-metadata" src="org.ametys.cms.contenttype.CommonSortableMetadataGenerator"/>
 
             <map:generator name="profile-rights" src="org.ametys.cms.rights.ProfileRightsGenerator"/>
@@ -359,6 +360,14 @@
                 <map:serialize type="xml"/>
             </map:match>
             
+            <map:match pattern="common-typed-metadata">
+                <map:generate type="common-typed-metadata"/>
+                <map:transform type="i18n" label="xml">
+                    <map:parameter name="locale" value="{locale:locale}"/>
+                </map:transform>
+                <map:serialize type="xml"/>
+            </map:match>
+            
             <map:match pattern="common-sortable-metadata">
                 <map:generate type="common-sortable-metadata"/>
                 <map:transform type="i18n" label="xml">
Index: main/plugin-cms/i18n/messages_en.xml
===================================================================
--- main/plugin-cms/i18n/messages_en.xml	(revision 26960)
+++ main/plugin-cms/i18n/messages_en.xml	(working copy)
@@ -1017,6 +1017,9 @@
     <message key="WIDGET_RICH_TEXT_HIERARCHY_ERROR">The title hierarchy is invalid.</message>
     <message key="WIDGET_RICH_TEXT_TOC_ERROR">Some text is present on the same line as a table of contents.</message>
     
+    <message key="WIDGET_SELECTTYPEDMETADATA_FILTER_NONE">None</message>
+   	<message key="WIDGET_SELECTTYPEDMETADATA_FILTER_LOAD_ERROR">An error occurred in the loading of the metadatas</message>
+    
     <message key="WIDGET_COMBOBOX_ALL_OPTIONS">- All -</message>
     
     <!-- +
Index: main/plugin-cms/i18n/messages_fr.xml
===================================================================
--- main/plugin-cms/i18n/messages_fr.xml	(revision 26960)
+++ main/plugin-cms/i18n/messages_fr.xml	(working copy)
@@ -1018,6 +1018,9 @@
     <message key="WIDGET_RICH_TEXT_HIERARCHY_ERROR">La hiérarchie des titres est incorrecte.</message>
     <message key="WIDGET_RICH_TEXT_TOC_ERROR">Du texte est présent sur la même ligne qu'une table des matières.</message>
     
+    <message key="WIDGET_SELECTTYPEDMETADATA_FILTER_NONE">Aucune</message>
+    <message key="WIDGET_SELECTTYPEDMETADATA_FILTER_LOAD_ERROR">Il y a eu une erreur dans le chargement des métadatas</message>
+    
     <message key="WIDGET_COMBOBOX_ALL_OPTIONS">- Tous -</message>
      
     <!-- +
Index: main/plugin-cms/resources/js/org/ametys/cms/widgets/SelectTypedMetadata.i18n.js
===================================================================
--- main/plugin-cms/resources/js/org/ametys/cms/widgets/SelectTypedMetadata.i18n.js	(revision 0)
+++ main/plugin-cms/resources/js/org/ametys/cms/widgets/SelectTypedMetadata.i18n.js	(revision 0)
@@ -0,0 +1,140 @@
+/*
+ *  Copyright 2014 Anyware Services
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+Ext.namespace('org.ametys.cms.widgets');
+
+//Register widget
+org.ametys.utils.Widgets.registerWidget ('string', 'typed-metadata', 'org.ametys.cms.widgets.SelectTypedMetadata');
+
+org.ametys.cms.widgets._metadataSetName = "index";
+
+org.ametys.cms.widgets.SelectTypedMetadata = function(config, enumeratedValues) 
+{
+	this.store = new Ext.data.SimpleStore({
+		idIndex: 0,
+        fields: [
+           {name: 'value'},
+           {name: 'label'}        
+        ]
+	});
+	
+	this._metadataSetName = org.ametys.cms.widgets._metadataSetName;
+
+	org.ametys.cms.widgets.SelectTypedMetadata.superclass.constructor.call(this, config, enumeratedValues);
+};
+
+Ext.extend(org.ametys.cms.widgets.SelectTypedMetadata, org.ametys.form.ComboField, {
+	height: 107,
+	width: 100,
+	minChars: 0, 
+	triggerAction: 'all',
+	forceSelection: true,
+	selectOnFocus: true,
+	valueField: 'value',
+	displayField: 'label',
+	mode: 'local'
+});
+
+/**
+ * Force expand on focus
+ */
+org.ametys.cms.widgets.SelectTypedMetadata.prototype._onFocus = function ()
+{
+	if(this.triggerAction == 'all') 
+	{
+        this.doQuery(this.allQuery, true);
+    } 
+	else 
+	{
+        this.doQuery(this.getRawValue());
+    }
+}
+
+org.ametys.cms.widgets.SelectTypedMetadata.prototype.onSelectContentTypes = function (cTypes)
+{
+	this._cTypes = cTypes;
+	this._metadataSetName = org.ametys.cms.widgets._metadataSetName;
+	this._loadSkins();
+}
+
+org.ametys.cms.widgets.SelectTypedMetadata.prototype.onRender = function(ct, position)
+{
+	org.ametys.cms.widgets.SelectTypedMetadata.superclass.onRender.call(this, ct, position);
+	this._loadSkins();
+
+	this.addListener('focus', this._onFocus, this);
+	
+	org.ametys.cms.widgets.ContentTypesWidget.registerListener (this);
+}
+
+org.ametys.cms.widgets.SelectTypedMetadata.prototype._loadSkins = function ()
+{
+	params = {};
+	params.ids = this._cTypes;
+	params.metadataSetName = this._metadataSetName;
+
+	var firstLoad = false;
+	if (typeof this._cTypes == 'undefined')
+	{
+		firstLoad = true;
+	}
+	
+	var serverMessage = new org.ametys.servercomm.ServerMessage('cms', '/common-typed-metadata', params, org.ametys.servercomm.ServerComm.PRIORITY_MAJOR, this._loadSkinsCb, this, [firstLoad]);
+	org.ametys.servercomm.ServerComm.getInstance().send(serverMessage);
+}
+
+org.ametys.cms.widgets.SelectTypedMetadata.prototype._loadSkinsCb = function (response, args)
+{
+	if (org.ametys.servercomm.ServerComm.handleBadResponse("<i18n:text i18n:key="WIDGET_SELECTTYPEDMETADATA_FILTER_LOAD_ERROR"/>", response, "org.ametys.web.administration.SkinsWidget"))
+	{
+		return;
+	}
+	
+	var store = this.getStore();
+	store.removeAll();	
+	
+	var metadataTab = [];
+	
+	var metadatas = response.selectNodes("metadata/metadata");
+	
+	var noData = {
+            value: "",
+            label: "<i18n:text i18n:key="WIDGET_SELECTTYPEDMETADATA_FILTER_NONE"/>"
+    };
+	metadataTab.push(new this.store.recordType(noData));
+
+	for (var i=0; i &lt; metadatas.length; i++)
+	{
+		var data = {
+	            value: metadatas[i].getAttribute('name'),
+	            label: metadatas[i].selectSingleNode('label')[org.ametys.servercomm.ServerComm.xmlTextContent]
+	    };
+
+		metadataTab.push(new this.store.recordType(data));
+	}
+	
+	this.store.add(metadataTab);
+	
+	// We set the value after the loading of the store
+	this.setValue(this.getValue());
+	
+	// Check if it's the first time we load (cType is not defined before first load)
+	var firstLoad = args[0];
+	if (!firstLoad &amp;&amp; this.store.find('value',this.getValue()) == -1 )
+	{
+		this.setValue("");
+	}
+}
\ No newline at end of file
Index: main/plugin-cms/src/org/ametys/cms/contenttype/CommonTypedMetadataGenerator.java
===================================================================
--- main/plugin-cms/src/org/ametys/cms/contenttype/CommonTypedMetadataGenerator.java	(revision 0)
+++ main/plugin-cms/src/org/ametys/cms/contenttype/CommonTypedMetadataGenerator.java	(revision 0)
@@ -0,0 +1,232 @@
+/*
+ *  Copyright 2010 Anyware Services
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.ametys.cms.contenttype;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.generation.ServiceableGenerator;
+import org.apache.cocoon.xml.AttributesImpl;
+import org.apache.cocoon.xml.XMLUtils;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.StringUtils;
+import org.xml.sax.SAXException;
+
+import org.ametys.cms.lucene.FieldNames;
+import org.ametys.runtime.util.I18nizableText;
+
+/**
+ * SAX common metadata given content types and metadata-set
+ */
+public class CommonTypedMetadataGenerator extends ServiceableGenerator
+{
+    /** The content type extension point */
+    protected ContentTypeExtensionPoint _contentTypeEP;
+    
+    @Override
+    public void service(ServiceManager smanager) throws ServiceException
+    {
+        super.service(smanager);
+        _contentTypeEP = (ContentTypeExtensionPoint) smanager.lookup(ContentTypeExtensionPoint.ROLE);
+    }
+    
+    @Override
+    public void generate() throws IOException, SAXException, ProcessingException
+    {
+        Request request = ObjectModelHelper.getRequest(objectModel);
+        
+        String paramIds = request.getParameter("ids");
+        String metadataSetName = request.getParameter("metadataSetName");
+        String authorizedMetadataTypesAsString = "date"; // todo Should be a request parameter
+        
+        String[] authorizedMetadataTypes = StringUtils.split(authorizedMetadataTypesAsString);
+
+        boolean hasDocument = false;
+        
+        String[] ids = null;
+        if (!StringUtils.isEmpty(paramIds))
+        {
+            ids = paramIds.split(",");
+        }
+        else
+        {
+            ids =  getAllAvailablesContentTypes(request, true);
+            hasDocument = true;
+        }
+        
+        Map<String, I18nizableText> metadataLabels = new HashMap<String, I18nizableText>();
+        Map<String, MetadataType> commonMetadataNames = null;
+        
+        if (StringUtils.isNotEmpty(metadataSetName))
+        {
+            for (String id : ids)
+            {
+                ContentType contentType = _contentTypeEP.getExtension(id);
+                
+                // Documents are not a content-type
+                if (!id.equals("resource"))
+                {
+                    MetadataSet metadataSet = contentType.getMetadataSetForView(metadataSetName);
+                    
+                    // Test if the metadataSetName view is defined
+                    if (metadataSet != null)
+                    {
+                        Map<String, MetadataType> metadataNames = new HashMap<String, MetadataType>();
+                        _getTypedMetadata(contentType, metadataSet, authorizedMetadataTypes, metadataNames, metadataLabels);
+                        
+                        if (commonMetadataNames == null)
+                        {
+                            commonMetadataNames = metadataNames;
+                        }
+                        else
+                        {
+                            // Maps intersection
+                            commonMetadataNames.keySet().retainAll(metadataNames.keySet());
+                        }
+                    }
+                }
+                else
+                {
+                    hasDocument = true;
+                }
+            }
+        }
+        
+        saxCommonMetadata (commonMetadataNames, metadataLabels, hasDocument);
+    }
+
+    private void _getTypedMetadata(MetadataDefinitionHolder metadataDefHolder, MetadataSetElement metadataSetElement, String[] authorizedMetadataTypes, Map<String, MetadataType> metadataNames, Map<String, I18nizableText> metadataLabels)
+    {
+        for (MetadataSetElement subMetadataSetElement : ((Fieldset) metadataSetElement).getElements())
+        {
+            if (metadataSetElement instanceof MetadataDefinitionReference)
+            {
+                String metadataName = ((MetadataDefinitionReference) subMetadataSetElement).getMetadataName();
+                MetadataDefinition metaDef = metadataDefHolder.getMetadataDefinition(metadataName);
+                // todo String metadataId = metaDef.getId();
+                
+                if (ArrayUtils.contains(authorizedMetadataTypes, metaDef.getType()))
+                {
+                    metadataNames.put(metadataName, metaDef.getType());
+                    
+                    I18nizableText label = metaDef.getLabel();
+                    metadataLabels.put(metadataName, label);
+                }
+                
+                if (metaDef.getType() == MetadataType.COMPOSITE) // todo is repeater included ?
+                {
+                    // TODO
+                }
+            }
+            else
+            {
+                // TODO
+                // _getTypedMetadata(metadataDefHolder, subMetadataSetElement, authorizedMetadataTypes, metadataNames, metadataLabels);
+            }
+        }
+    }
+    
+    /**
+     * SAX the common metadata
+     * @param commonMetadataNames the name of metadata to SAX
+     * @param metadataLabels all metadata labels
+     * @param hasDocument true if there is documents in between
+     * @throws SAXException if an error occurred while saxing
+     */
+    protected void saxCommonMetadata (Map<String, MetadataType> commonMetadataNames, Map<String, I18nizableText> metadataLabels, boolean hasDocument) throws SAXException
+    {
+        contentHandler.startDocument();
+        XMLUtils.startElement(contentHandler, "metadata");
+        
+        // If "Document" is not selected in the list
+        if (!hasDocument)
+        {
+            Map<String, I18nizableText> commonMetadata = new HashMap<String, I18nizableText>();
+            
+            if (metadataLabels != null && commonMetadataNames != null)
+            {
+                for (String metadataName : metadataLabels.keySet())
+                {
+                    if (commonMetadataNames.containsKey(metadataName))
+                    {
+                        commonMetadata.put(metadataName, metadataLabels.get(metadataName));
+                    }
+                }
+                
+                for (String name : commonMetadata.keySet())
+                {
+                    AttributesImpl attrs = new AttributesImpl();
+                    attrs.addCDATAAttribute("name", name);
+                    
+                    MetadataType metadataType = commonMetadataNames.get(name);
+                    attrs.addCDATAAttribute("type", metadataType.toString());
+                    
+                    XMLUtils.startElement(contentHandler, "metadata", attrs);
+                    commonMetadata.get(name).toSAX(contentHandler, "label");
+                    XMLUtils.endElement(contentHandler, "metadata");
+                }
+            }
+            
+            // Always add "Last validation"
+            AttributesImpl attrs = new AttributesImpl();
+            attrs.addAttribute("", "name", "name", "CDATA", FieldNames.LAST_VALIDATION);
+            attrs.addAttribute("", "type", "type", "CDATA", MetadataType.DATE.toString());
+            XMLUtils.startElement(contentHandler, "metadata", attrs);
+            new I18nizableText("plugin.web", "PLUGINS_WEB_LAST_VALIDATION_DATE").toSAX(contentHandler, "label");
+            XMLUtils.endElement(contentHandler, "metadata");
+        }
+
+        // Always add "Last modified"
+        AttributesImpl attrs = new AttributesImpl();
+        attrs.addAttribute("", "name", "name", "CDATA", FieldNames.LAST_MODIFIED);
+        attrs.addAttribute("", "type", "type", "CDATA", MetadataType.DATE.toString());
+        XMLUtils.startElement(contentHandler, "metadata", attrs);
+        new I18nizableText("plugin.web", "PLUGINS_WEB_LAST_MODIFICATION_DATE").toSAX(contentHandler, "label");
+        XMLUtils.endElement(contentHandler, "metadata");
+        
+        XMLUtils.endElement(contentHandler, "metadata");
+        contentHandler.endDocument();
+    }
+    
+    /**
+     * Get all the available content types 
+     * @param request the request
+     * @param publicOnly Only the non private content types will be returned
+     * @return all the available content types 
+     */
+    protected String[] getAllAvailablesContentTypes (Request request, boolean publicOnly)
+    {
+        Set<String> publicTypes = new HashSet<String>();
+        
+        for (String id : _contentTypeEP.getExtensionsIds())
+        {
+            if (!publicOnly || !_contentTypeEP.getExtension(id).isPrivate())
+            {
+                publicTypes.add(id);
+            }
+        }
+        
+        return publicTypes.toArray(new String[publicTypes.size()]);
+    }
+}
\ No newline at end of file